package com.chigga.application.hanlder.login;

import com.chigga.common.core.domain.ResponseResult;
import com.chigga.common.utils.JSON;
import com.chigga.common.utils.JwtUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 登录/身份认证成功处理器
 *
 * @author DefChigga
 */
@Component
public class LoginSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler implements AuthenticationSuccessHandler {

    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    @Resource
    private JwtUtil jwtUtil;

    public LoginSuccessHandler() {
        this.setRedirectStrategy((request, response, url) -> {
            // 更改重定向策略，前后端分离项目，后端使用RestFul风格，无需做重定向
            // Do nothing, no redirects in REST
        });
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        Object principal = authentication.getPrincipal();
        if (!(principal instanceof UserLoginInfo)) {
            throw new RuntimeException("登录认证成功后，authentication.getPrincipal()返回的Object对象必须是：UserLoginInfo！");
        }
        UserLoginInfo currentUser = (UserLoginInfo) principal;
        currentUser.setSessionId(UUID.randomUUID().toString());
        Map claims = JSON.parse(JSON.stringify(currentUser), HashMap.class);
        // 生成 token 和 refreshToken
        Map<String, Object> responseData = new LinkedHashMap<>();
        responseData.put("token", jwtUtil.createToken(claims));
//        responseData.put("refreshToken", jwtUtil.createToken(claims));

        // 一些特殊的登录参数。比如三方登录，需要额外返回一个字段是否需要跳转的绑定已有账号页面
        Object details = authentication.getDetails();
        if (details instanceof Map) {
            Map detailsMap = (Map) details;
            responseData.putAll(detailsMap);
        }

        // 虽然APPLICATION_JSON_UTF8_VALUE过时了，但也要用。因为Postman工具不声明utf-8编码就会出现乱码
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        PrintWriter writer = response.getWriter();
        writer.print(JSON.stringify(ResponseResult.success(responseData, "登录成功")));
        writer.flush();
        writer.close();
    }
}
